package com.jjt.kiki.ip;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import com.jjt.kiki.bean.Ip;
import com.jjt.kiki.ip.strategy.IpCrawlerStrategy;
import com.jjt.kiki.service.IpService;
import com.machinepublishers.jbrowserdriver.JBrowserDriver;

public class IpCrawler implements Runnable {

	private IpCrawlerStrategy strategy = null;
	private long delay = 0;
	private boolean isStop = false;
	private Logger logger = Logger.getLogger(IpCrawler.class);
	private IpService ipService = new IpService();

	public IpCrawler(IpCrawlerStrategy strategy, long delay) {
		this.strategy = strategy;
		this.delay = delay;
	}

	public void stop() {
		this.isStop = true;
	}

	@Override
	public void run() {
		while (true) {
			if (isStop)
				return;
			List<Ip> ips = new ArrayList<Ip>();

			// logger.info("开始执行请求");
			if (strategy.isBrowser()) {
				JBrowserDriver driver=null;
				try {
					driver = new JBrowserDriver();
					driver.get(strategy.getAddress());
					driver.pageWait();
					// logger.info("开始执行分析");
					ips = strategy.analyse(driver.getPageSource());
				} catch (Exception e) {
					logger.info(e);
					e.printStackTrace();
				}finally {
					if(driver!=null) {
						driver.quit();
						if(driver!=null)
							driver.kill();
					}
				}
			} else {
				CloseableHttpClient hc = null;
				CloseableHttpResponse response = null;
				try {
					HttpGet get = new HttpGet(strategy.getAddress());
					hc = HttpClients.createDefault();
					response = hc.execute(get);
					// logger.info("开始执行分析");
					ips = strategy.analyse(EntityUtils.toString(response.getEntity()));
				} catch (Exception e) {
					logger.info(e);
//					e.printStackTrace();
				}finally {
					if(hc!=null) {
						if(response!=null) {
							try {
								EntityUtils.consume(response.getEntity());
								response.close();
							} catch (IOException e) {
								// 
								e.printStackTrace();
							}
						}
						try {
							hc.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}

			for (Ip ip : ips) {
				if (isVaild(ip))
					ipService.save(ip);
			}
			try {
				Thread.sleep(delay);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public boolean isVaild(Ip ip) {
		CloseableHttpClient hc = HttpClients.createDefault();
		logger.info(ip.getIpHost() + ":" + ip.getIpPort() + "开始有效检测");
		HttpGet get = new HttpGet("https://www.baidu.com");
		RequestConfig.Builder builder = RequestConfig.custom().setConnectTimeout(3000).setSocketTimeout(3000)
				.setProxy(new HttpHost(ip.getIpHost(), ip.getIpPort())).setConnectionRequestTimeout(3000);
		get.setConfig(builder.build());
		CloseableHttpResponse response = null;
		try {
			// logger.info("开始执行验证");
			response = hc.execute(get);
			int statuCode = response.getStatusLine().getStatusCode();
			if (statuCode == 200) {
				logger.info("ProxyOffer: ip :" + ip.getIpHost() + ":" + ip.getIpPort() + " 验证成功");
				return true;
			} else {
				// logger.info("ProxyOffer: ip :" +
				// ip.getIpHost()+":"+ip.getIpPort() + " 验证失败");
				return false;
			}
		} catch (Exception e) {
			// logger.info("ProxyOffer:该代理ip请求失败，发生异常");
			e.printStackTrace();
		}finally {
			if(hc!=null) {
				if(response!=null) {
					try {
						EntityUtils.consume(response.getEntity());
						response.close();
					} catch (IOException e) {
						// 
						e.printStackTrace();
					}
				}
				try {
					hc.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return false;
	}

	public static void main(String[] args) {

	}
}
